package com.forest.oss.impl.mobilecloud;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import com.forest.oss.AbstractOssClient;
import com.forest.oss.constants.AclType;
import com.forest.oss.impl.OssProperties;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.stream.Collectors;


public class MobileOssClient extends AbstractOssClient {

    private static final Logger log = LoggerFactory.getLogger(MobileOssClient.class);

    private MobileOssProperties mobileOssProperties;
    private AmazonS3 client;

    public MobileOssClient(MobileOssProperties mobileOssProperties){
        System.out.println("--------------加载移动云对象存储------------");
        this.mobileOssProperties = mobileOssProperties;
        this.client = getOssClient();
    }

    private AmazonS3 getOssClient() {
        AWSCredentials credentials = new BasicAWSCredentials(mobileOssProperties.getAppKeyId(), mobileOssProperties.getAppSecret());
        AwsClientBuilder.EndpointConfiguration configuration = new AwsClientBuilder.EndpointConfiguration(mobileOssProperties.getEndPoint(), Regions.CN_NORTH_1.getName());
        return AmazonS3ClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                .withEndpointConfiguration(configuration)
                .build();
    }

    @Override
    public OssProperties getProperties() {
        return this.mobileOssProperties;
    }

    @Override
    public String getFolder() {
        return super.getFolder(mobileOssProperties.getProject());
    }

    @Override
    public String upload(String key, String folder, InputStream inputStream, AclType acl) {
        // 上传同时设置访问权限
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentType(getContentType(key));
        try {
            metadata.setContentLength(inputStream.available());
        } catch (IOException e) {
            log.error("获取文件流有限内容长度异常：{}", e.getMessage(), e);
        }

        PutObjectRequest request = new PutObjectRequest(mobileOssProperties.getBucket(), folder + key, inputStream, metadata);
        request.setCannedAcl(CannedAccessControlList.valueOf(acl.name()));
        client.putObject(request);
        return folder + key;
    }

    @Override
    public InputStream download(String key) {
        S3Object object = client.getObject(mobileOssProperties.getBucket(), key);
        S3ObjectInputStream stream = object.getObjectContent();
        byte [] content = IoUtil.readBytes(stream);
        return new ByteArrayInputStream(content);
    }

    @Override
    public void delete(String key) {
        client.deleteObject(mobileOssProperties.getBucket(), key);
    }

    @Override
    public List<String> batchDelete(List<String> keys, boolean quiet) {
        Assert.isTrue(CollectionUtils.isEmpty(keys), "删除的文件keys不能为空");
        Assert.isTrue(keys.size() > 1000, "删除的文件keys超过了最大限制1000个");
        DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(mobileOssProperties.getBucket())
                .withKeys(keys.stream().map(k -> new DeleteObjectsRequest.KeyVersion(k)).collect(Collectors.toList()))
                .withQuiet(quiet);
        DeleteObjectsResult result = client.deleteObjects(deleteObjectsRequest);
        List<String> res = result.getDeletedObjects().stream().map(DeleteObjectsResult.DeletedObject::getKey).collect(Collectors.toList());
        return res;
    }

    @Override
    public String getFile(String key, AclType acl) {
        if(StrUtil.equalsIgnoreCase(CannedAccessControlList.PublicRead.name(), acl.name())) {
            return buildPublicUrl(mobileOssProperties.getBucketDomain(), key);
        } else {
            String url = client.getUrl(mobileOssProperties.getBucket(), key).getPath();
            return url;
        }
    }

    @Override
    public Boolean exists(String key) {
        return client.doesObjectExist(mobileOssProperties.getBucket(), key);
    }
}
